package com.ruoyi.project.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.project.domain.dto.DictDataDTO;
import com.ruoyi.project.domain.entity.DictData;
import com.ruoyi.project.mapper.DictDataMapper;
import com.ruoyi.project.service.DictDataService;
import org.springframework.stereotype.Service;

import lombok.AllArgsConstructor;

import java.util.*;
import java.util.stream.Collectors;

/**
 * (DictData)表服务实现类
 *
 * @author yanweichao
 * @since 2025-06-25 15:52:21
 */
@Service
@AllArgsConstructor
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper, DictData> implements DictDataService {

    protected LambdaQueryWrapper<DictData> queryWrapper(DictDataDTO param) {
        return new LambdaQueryWrapper<DictData>()
            .like(StrUtil.isNotEmpty(param.getKeyword()), DictData::getDictName, param.getKeyword())
            .eq(ObjectUtil.isNotNull(param.getParentId()), DictData::getParentId, param.getParentId())
            .eq(ObjectUtil.isNotNull(param.getTopId()), DictData::getTopId, param.getTopId())
            .orderByAsc(DictData::getId);
    }

    @Override
    public List<DictData> queryList(DictDataDTO param) {
        return this.list(queryWrapper(param));
    }

    private List<DictData> queryChildren(Integer id) {
        DictDataDTO param = new DictDataDTO();
        param.setParentId(id);
        return this.list(queryWrapper(param));
    }

    private List<DictData> queryAllChildren(Integer id) {
        DictDataDTO param = new DictDataDTO();
        param.setTopId(id);
        return this.list(queryWrapper(param));
    }

    private void findChild(Map<Integer, List<DictDataDTO>> dictMap, DictDataDTO dto) {
        if (dictMap.containsKey(dto.getId())) {
            List<DictDataDTO> list = dictMap.get(dto.getId());
            for (DictDataDTO dict : list) {
                findChild(dictMap, dict);
            }
            dto.setChildren(list);
        }
    }

    @Override
    public List<DictDataDTO> queryTree(DictDataDTO param) {
        List<DictDataDTO> result = new ArrayList<>();
        List<DictDataDTO> list = new ArrayList<>();
        for (DictData dict : this.queryList(param)) {
            list.add(DictDataDTO.of(dict));
        }
        Map<Integer, List<DictDataDTO>> dictMap = list.stream().collect(Collectors.groupingBy(DictData::getParentId));
        if (!dictMap.isEmpty()) {
            for (DictDataDTO data : dictMap.get(0)) {
                findChild(dictMap, data);
                result.add(data);
            }
        }
        return result;
    }

    @Override
    public DictDataDTO getDtoById(Integer id) {
        DictData entity = this.getById(id);
        DictDataDTO dto = DictDataDTO.of(entity);
        if (dto.getParentId() == 0) {
            dto.setMaxGrade(this.queryAllChildren(dto.getId()).stream().mapToInt(DictData::getGrade).max().orElse(2));
        }
        dto.setFullType_1(dto.getFullType());
        dto.setFullName_1(dto.getFullName());
        if (StrUtil.contains(dto.getFullType(), "/")) {
            Map<String, String> map = new HashMap<String, String>() {{
                int a = 1, b = 1;
                for (String s : StrUtil.split(dto.getFullType(), "/")) {
                    put("fullType_" + (a++), s);
                }
                for (String s : StrUtil.split(dto.getFullName(), "/")) {
                    put("fullName_" + (b++), s);
                }
            }};
            DictDataDTO dt = BeanUtil.mapToBean(map, DictDataDTO.class, false, null);
            BeanUtil.copyProperties(dt, dto, CopyOptions.create().setIgnoreNullValue(true));
        }
        return dto;
    }

    @Override
    public boolean saveOrUpdate(DictDataDTO param) {
        return param.isNew() ? this.save(param) : this.updateById(param);
    }
}
